package com.project.easy.common.log.core;

import com.project.easy.common.log.core.dto.WriteLogDto;
import com.project.easy.common.log.core.service.ILogPersistent;
import com.project.easy.common.log.core.service.ILogQueryExtend;
import  com.project.easy.common.util.date.DateTool;
import  com.project.easy.common.util.string.StringUtil;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.project.easy.common.util.constants.CommonIntConstant.*;

/**
 * @ClassName PersistentProcessor
 * @Description 日志处理器
 * @Author GreatorMan.cool
 * @Date 2021/3/19 10:21
 * @Version 1.0
 **/
public final class PersistentProcessor {
    /**
     * 私有构造方法
     */
    private PersistentProcessor() {

    }
    /**
     * 是否初始化成功
     */
    private   static   Boolean hasInit = Boolean.FALSE;
    /**
     *日志线程池
     */
    public  static  final  ExecutorService WRITELOG_EXECUTOR = new ThreadPoolExecutor(1, 1,
            0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    /**
     * 日志持久化
     */
    private static ILogPersistent iPersistentLog;
    /**
     * 获取当前用户信息
     */
    private  static ILogQueryExtend iQueryExtend;

    private  static Integer  writeLog = TWO_THOUSAND;
    /**
     *  日志工作队列
     */
    private  static LinkedBlockingQueue<WriteLogDto> writeLogQueue;

    /**
     * 外界在初始之前可以初始化这个数据
     * @param writeLog 日志队列个数
     */
    public static void setWriteLog(Integer writeLog) {
        PersistentProcessor.writeLog = writeLog;
    }
    /**
     * 初始化
     * @param persistentLog 持久化
     */
    public  static void  init(ILogPersistent persistentLog) {
        writeLogQueue = new LinkedBlockingQueue<>();
        iPersistentLog = persistentLog;
        if (!Objects.isNull(iPersistentLog)) {
            hasInit = Boolean.TRUE;
        }
    }
    /**
     * 日志写入
     */
    public  static  void run() {
        WRITELOG_EXECUTOR.submit((Runnable) () -> {
            while (true) {
                try {
                    WriteLogDto poll = writeLogQueue.poll(TWENTY, TimeUnit.SECONDS);
                    if (!Objects.isNull(poll)) {
                        poll.setInput(StringUtil.cutLenStr(poll.getInput(), TWO_THOUSAND));
                        poll.setContent(StringUtil.cutLenStr(poll.getContent(), TWO_THOUSAND));
                        poll.setCreateTime(new Date());
                        poll.setExpirTime(DateTool.addMonths(poll.getCreateTime(), TWELVE));
                        iPersistentLog.save(poll);
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });
        hasInit = Boolean.TRUE;
    }
    /**
     * 日志写入到队列中
     * @param writeLogDto 日志对象
     * @return 是否成功
     */
    public  static  Boolean write(WriteLogDto writeLogDto) {
        if (hasInit && !Objects.isNull(writeLogDto)) {
            writeLogQueue.add(writeLogDto);
        }
        return Boolean.TRUE;
    }

}
